#ifndef _KERNEL_H_INCLUDED_
#define _KERNEL_H_INCLUDED_

#include "defines.h"
#include "syscall.h"
#include "interrupt.h"

#define THREAD_NUM 16

typedef struct _kz_context {
    uint32 sp;
} kz_context;

typedef struct _kz_thread {
    kz_thread_id_t id;
    struct _kz_thread *next;
    char name[THREAD_NAME_SIZE + 1];
    int priority;
    char *stack;
    unsigned stacksize;
    uint16 flags;
#define THREAD_ALIVE        ((uint16)1 << 0)
#define THREAD_READY        ((uint16)1 << 1)
#define THREAD_WAITMSG      ((uint16)1 << 2)
#define THREAD_WAITALARM    ((uint16)1 << 3)
    uint32 alarm_count;
    struct {
        kz_func_t func;
        int argc;
        char **argv;
    } init;
    struct {
        kz_syscall_type_t type;
        kz_syscall_param_t *param;
    } syscall;
    kz_context context;
} kz_thread;

extern kz_thread threads[];
extern int in_thread;
extern kz_thread *current;

int putready(kz_thread *p);
void thread_wakeup(kz_thread *thp);

kz_thread_id_t sys_run(kz_func_t func, char *name, int priority, unsigned stacksize, int argc, char *argv[]);
int sys_wakeup(kz_thread_id_t id);
void *sys_kmalloc(int size);
int sys_kmfree(void *p);
int sys_send(kz_msgbox_id_t id, int size, char *p, int priority);
int sys_setintr(softvec_type_t type, kz_handler_t handler);
kz_thread_info_t *sys_getthreads(int *sizep);
kz_msgbox_id_t sys_getmsgbox();
int sys_freemsgbox(kz_msgbox_id_t id);
int sys_resource();
uint32 sys_systime();

#endif
